package uk.ac.lkl.lpp.ui;
import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;

import javax.swing.*;

import uk.ac.lkl.common.ui.SlidePanel;
import uk.ac.lkl.lpp.xml.XSLTConvertor;
import uk.ac.lkl.lpp.PedagogyPlan;

import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import java.util.Vector;
import java.util.prefs.*;

/**
 * Dialog for user to invoke exporting the plan to varios formats.
 * VERY flaky. needs deep restructuring.
 * 
 * @author Uri
 *
 */
public class ExportDialog extends JDialog{
	private static final long serialVersionUID = 4560081606574094994L;
	String exportPath;
	String extention;
	String xslFileName;
	String outFileName;
	
	File xmlFile;
	File outFile;
	File xsltFile;
	
	JTextField filePath;
	JFileChooser fileChooser;
	PedagogyPlan plan;
	//Properties properties;
	JPanel mainPanel;
	
	Preferences userPrefs=null;
	Hashtable parameters = new Hashtable();
	
	Properties defProps;
	Properties userProps;
	String userPropsFileName="user.properties";
	//Plan Components
	JCheckBox aimsCheckBox;
	JCheckBox objectivesCheckBox;
	JCheckBox propertiesCheckBox;
	JCheckBox linkingCheckBox;	
	
	/**
	 * This is the dialog for exporting, it uses XSLTConvertor to export, and the 
	 * Uri: add some blurb here.
	 * @param planFile
	 * @param p
	 */
	public ExportDialog(File planFile,PedagogyPlan p){
		mainPanel=new JPanel();
		
		GridBagLayout gridBag = new GridBagLayout();
		GridBagConstraints c = new GridBagConstraints();
		
		mainPanel.setLayout(gridBag);
		
		plan = p;
		xmlFile = planFile;
		setup();
		outFile = new File(outFileName);
		xsltFile= new File(xslFileName);		
		
		fileChooser=new JFileChooser();

		filePath = new JTextField();
		
		filePath.setText(outFile.getAbsolutePath()+extention);
		
		
		JButton browseBut = new JButton("Browse");
		browseBut.addActionListener(new ActionListener(){

			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				int ret=fileChooser.showSaveDialog(null);
				if(ret!=JFileChooser.CANCEL_OPTION){
					outFile = fileChooser.getSelectedFile();
					userPrefs.put("ExportPath", outFile.getParent()+File.separatorChar);
					update();
				}
			}
		});
		
			
		
		JButton okBut = new JButton("OK");
		okBut.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e) {
				try{
					export();
					
				}catch(Exception ex){
					ex.printStackTrace();
				}
			}
		});
		
		JButton cancelBut = new JButton("Cancel");
		cancelBut.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				close();
			}
		});
		
		
		AdvancedOptionsDrawer adv = new AdvancedOptionsDrawer();

		//Layout
		c.anchor=GridBagConstraints.FIRST_LINE_START;
		c.fill=GridBagConstraints.HORIZONTAL;
		c.gridy=0;
		mainPanel.add(filePath,c);
		mainPanel.add(browseBut,c);	
		c.gridy=1;
		c.fill=GridBagConstraints.NONE;
		c.anchor=GridBagConstraints.LINE_START;
		mainPanel.add(okBut,c);
		
		mainPanel.add(cancelBut,c);
		c.gridy=2;
		c.fill=GridBagConstraints.HORIZONTAL;
		mainPanel.add(adv,c);
		
		this.add(mainPanel);
		this.pack();		
	}
	
	
	/**
	 * Uri: add a comment saying what this does. the name is misleading. maybe rename to getOutputOptions.
	 * read the stuff from a properties file in the XSLTs directory.
	 * @return
	 */
	public String[] getLabels(){
		Enumeration e = userProps.propertyNames();

		Vector  lbls = new Vector();
		while(e.hasMoreElements()){
			String s = (String)e.nextElement();
			if(s.startsWith("Export")){
				String[] nas = s.split("\\.");
				lbls.add((String)nas[1]);
			}
		}
		lbls.add((String)"other...");
		String[] ret = new String[lbls.size()];
		lbls.toArray(ret);
		return ret;
	}
	
	
	/*
	 * 		
	 */

	public void getDefaults(){
		try{
			defProps = new Properties();
			defProps.load(this.getClass().getResourceAsStream("Messages.properties"));
			userProps = new Properties(defProps);
			File pf = new File(userPropsFileName);
			//User prop file
			if(pf.exists()){
				userProps.load(new FileInputStream(pf));
			}
		}catch(Exception e){
			e.printStackTrace();
		}	
	}

	
	public void getUserSettings()throws Exception{
		
		userPrefs = Preferences.userNodeForPackage(this.getClass());
		exportPath=userPrefs.get("ExportPath", "");
		String temp=userPrefs.get("XSLTFile", "resources"+File.separatorChar+"data"+File.separatorChar+"xslt"+File.separatorChar+"default.html.xsl;.html");
		String[] temp2 = temp.split(";");
		xslFileName = temp2[0];
		extention = temp2[1];
		//outFileName=exportPath+xmlFile.getName()+extention;		
		outFileName=userPrefs.get("ExportPath", "")+xmlFile.getName();
	}

	
	public void setup(){
		try{
			getUserSettings();
			getDefaults();
			
			//this.setPreferredSize(new Dimension(300,300));
			this.pack();
			this.setVisible(true);
		}catch(Exception e){
			e.printStackTrace();
		}
	}

	
	private void close(){
		super.setVisible(false);
	}
	
	/**
	 * Uri: add a comment to each method saying what it does, what it expects, what it assumes.
	 * @throws Exception
	 */
	private void export()throws Exception{
		// Uri: get filename from textbox
		// fetch all neccesary params (infile, outfile, xsltfile) here and not sooner
		String tempOut=outFile.getAbsolutePath()+extention;
		outFile=new File(tempOut);
		int ret=0;
		if(outFile.exists()) {ret = JOptionPane.showConfirmDialog(null,new String("A file with that name already exists, overwrite?"),"File exists",JOptionPane.YES_NO_OPTION,JOptionPane.WARNING_MESSAGE);};
		if(ret!=JOptionPane.NO_OPTION){
			setParameters();
			if(xsltFile.getPath().startsWith("resources")){
				//Resource xslt
				XSLTConvertor.convertFromResource(xmlFile.getAbsolutePath(), xslFileName, outFile.getAbsolutePath(),parameters);
			}else{
				//Normal xslt
				XSLTConvertor.convert(xmlFile, xsltFile, outFile,parameters);
			}
			close();
		}
		
		// Uri: consider wraping all the userPref stuff in an application-wide service.
		userPrefs.put("ExportPath",outFile.getParent()+File.separatorChar);
		//properties.setProperty("Export.outDir", outDir);
		
	}
	
	/*
	 * 			The advanced drawer class
	 */
	public void update(){
		exportPath=fileChooser.getSelectedFile().getPath();
		filePath.setText(outFile.getAbsolutePath()+extention);
		
	};
	public void setParameters(){
		if(aimsCheckBox.isSelected()){parameters.put((String)"exportAims", (String)"true");
		}else{parameters.put((String)"exportAims", (String)"false");}
		
		if(objectivesCheckBox.isSelected()){parameters.put((String)"exportObjectives", (String)"true");
		}else{parameters.put((String)"exportObjectives", (String)"false");}
		
		if(propertiesCheckBox.isSelected()){parameters.put((String)"exportProperties", (String)"true");
		}else{parameters.put((String)"exportProperties", (String)"false");}
		
		if(linkingCheckBox.isSelected()){parameters.put((String)"exportLinking", (String)"true");
		}else{parameters.put((String)"exportLinking", (String)"false");}
		
		
	}
	
	
	private class AdvancedOptionsDrawer extends SlidePanel{

		public AdvancedOptionsDrawer(){
			super("Advanced",null);

			JPanel advPayload = new JPanel();
			advPayload.setLayout(new BoxLayout(advPayload,BoxLayout.PAGE_AXIS));
			
			JComboBox xsltBox = new JComboBox(getLabels());
			
			
			// Plan Components
			JPanel planComponentsPayloadPanel = new JPanel();
			planComponentsPayloadPanel.setLayout(new BoxLayout(planComponentsPayloadPanel,BoxLayout.PAGE_AXIS));
			SlidePanel planComponentsSP = new SlidePanel("Plan's components to export",planComponentsPayloadPanel);
			aimsCheckBox = new JCheckBox("Aims",true);
			objectivesCheckBox = new JCheckBox("Objectives",true);
			propertiesCheckBox = new JCheckBox("Properties",true);
			linkingCheckBox = new JCheckBox("Linking",true);
			
			planComponentsPayloadPanel.add(aimsCheckBox);
			planComponentsPayloadPanel.add(objectivesCheckBox);
			planComponentsPayloadPanel.add(propertiesCheckBox);
			planComponentsPayloadPanel.add(linkingCheckBox);
			
			//Formating options
			JPanel formattingPayloadPanel= new JPanel();
			SlidePanel formattingOptionsSP = new SlidePanel("Formating options", formattingPayloadPanel);
			
			xsltBox.addActionListener(new ActionListener(){			
				public void actionPerformed(ActionEvent e){
					JComboBox jcb = (JComboBox)e.getSource();
					String sel = (String)jcb.getSelectedItem();
					if(sel.startsWith("other")){
						openXSLTfile();
					}else{
						openListedFile(sel);
						
					}
				}
			});		
					
			advPayload.add(xsltBox,BorderLayout.NORTH);
			advPayload.add(planComponentsSP,BorderLayout.CENTER);
			advPayload.add(formattingOptionsSP,BorderLayout.SOUTH);
			this.setPayload(advPayload);	
		}
		private void openXSLTfile(){
			fileChooser.setCurrentDirectory(new File(userPrefs.get("XSLTPath", "")));
			int ret = fileChooser.showOpenDialog(null);
			if(ret!=JFileChooser.CANCEL_OPTION){
				xsltFile = fileChooser.getSelectedFile();
				userPrefs.put("XSLTPath", xsltFile.getPath());
			}
		}
		private void openListedFile(String selection){
			//String temp = userPrefs.get("Export."+selection, "");
			String temp = userProps.getProperty("Export."+selection);
			String[] temp2 = temp.split(";");
			String tmpXSLT = temp2[0];
			extention =temp2[1];
			xsltFile = new File(tmpXSLT);
			//outFileName=exportPath+xmlFile.getName()+extention;
			outFileName=outFile.getAbsolutePath();
			
			outFile = new File(outFileName);
			filePath.setText(outFile.getAbsolutePath()+extention);
			userPrefs.put("XSLTFile", xsltFile.getPath()+";"+extention);
		}
		
	}
}